<template>
    <div class="interview-voice">
        <!-- 隐藏的触发按钮 -->
        <button ref="triggerBtn" @click="initAudioContext">开始面试</button>
        <!--  style="opacity: 0.01;" -->
        <!-- 面试时长 -->
        <div class="interview-timer">
            <span>{{ formatTime(duration) }}</span>
        </div>

        <!-- 顶部提示 -->
        <div class="top-tip" v-if="showTip">
            <van-notice-bar left-icon="volume-o" :scrollable="false" text="面试即将结束，时长不足5分钟无法查看面试结果">
            </van-notice-bar>
        </div>

        <!-- AI头像区域 -->
        <div class="ai-avatar">
            <div class="avatar-bg">
                <img src="/images/mine/ai-avatar.png" alt="AI面试官">
            </div>
            <!-- 语音状态文本 -->
            <div class="voice-status">
                <template v-if="!isUserSpeaking">
                    <span v-if="aiSpeaking">正在说话...</span>
                    <span v-else>等待你说话...</span>
                </template>
                <!-- 波形动画 -->
                <div v-else class="wave-animation">
                    <span v-for="i in 4" :key="i" class="wave-bar" :style="{ animationDelay: `${i * 0.1}s` }"></span>
                </div>
            </div>
        </div>

        <!-- 语音提示 -->
        <!-- <div class="voice-tip" v-if="showVoiceTip">
            <van-icon name="volume-o" />
            <span>请允许浏览器使用麦克风</span>
        </div> -->

        <!-- 底部控制栏 -->
        <div class="control-bar">
            <!-- 静音按钮 -->
            <div class="control-btn" :class="{ active: isMuted }" @click="toggleMute">
                <img :src="isMuted ? '/images/interview/volume-o.png' : '/images/interview/volume.png'" />
                <span>{{ isMuted ? '你已静音' : '静音' }}</span>
            </div>

            <!-- 打断按钮 -->
            <div class="interrupt-btn" @click="handleInterrupt" :class="{ disabled: !aiSpeaking }">
                <van-icon name="stop-circle-o" />
                <!-- 等待AI回答 -->
                <span>{{ aiSpeaking ? '停止播放' : '' }}</span>
            </div>

            <!-- 挂断按钮 -->
            <div class="control-btn hang-up" @click="showEndConfirm">
                <img src="/images/interview/close.png" />
                <span>挂断</span>
            </div>
        </div>

        <!-- 结束确认弹窗 -->
        <van-dialog v-model:show="showEndDialog" :title="duration < 300 ? '是否要提前结束面试？' : '结束面试'"
            :message="getEndDialogMessage()" show-cancel-button cancel-button-text="继续面试" confirm-button-text="结束面试"
            @confirm="handleHangUp" />
        <audio ref="ttsPlayer" style="display: none"></audio>
    </div>
</template>

<script setup>
    import { ref, onMounted, onBeforeUnmount } from 'vue'
    import { useRouter, useRoute } from 'vue-router'
    import { showToast, showDialog } from 'vant'
    import { interviewApi, interviewUrl } from '@/api/interview'
    import { useInterviewStore } from '@/store/modules/interview'

    const router = useRouter()
    const route = useRoute()
    const triggerBtn = ref(null)
    // 面试时长，单位为秒
    const duration = ref(0)
    // 初始可用时长
    const initialDuration = ref(0)
    // 实际面试时长（通过初始时长减去当前可用时长计算）
    const actualDuration = computed(() => initialDuration.value - duration.value)
    // 最小面试时长，单位为秒
    const MIN_DURATION = 300
    // 是否静音
    const isMuted = ref(false)
    // 用户说话状态
    const isUserSpeaking = ref(false)
    // AI说话状态
    const aiSpeaking = ref(false)
    const showTip = ref(false)
    const showVoiceTip = ref(true)
    const showEndDialog = ref(false)
    const isAudioPlaying = ref(false)
    const ttsPlayer = ref(null)
    const interviewRecordId = ref('')
    const interviewStore = useInterviewStore()
    let hasInterviewed = ref(null)
    let mediaStream = null  // 保存媒体流的引用

    // 音频相关变量
    let ws = null
    let audioContext = null
    let input = null
    let processor = null
    let accumulatedData = []
    const sampleRate = 16000
    const bufferSize = 4096
    let timer = null
    let audioSendTimer = null  // 专门用于音频发送的定时器

    // 音频发送函数
    const sendAudioData = () => {
        if (!ws || ws.readyState !== WebSocket.OPEN) return

        try {
            // 无论是否有数据，都要按时发送
            if (accumulatedData.length > 0) {
                // 发送1秒的音频数据
                const dataToSend = accumulatedData.slice(0, sampleRate)
                ws.send(new Int16Array(dataToSend).buffer)
                accumulatedData = accumulatedData.slice(Math.min(sampleRate, accumulatedData.length))
                console.log("Sent audio data, length:", dataToSend.length)
            } else {
                // 发送空数据包保持连接
                ws.send(new Int16Array(sampleRate).buffer)
                console.log("Sent empty audio data")
            }
        } catch (error) {
            console.error('发送音频数据失败:', error)
        }
    }

    // 初始化音频上下文
    const initAudioContext = async () => {
        try {
            // 先获取音频设备权限
            const stream = await navigator.mediaDevices.getUserMedia({
                audio: {
                    channelCount: 1,
                    sampleRate: sampleRate,
                    echoCancellation: true,
                    noiseSuppression: true
                }
            })

            // 保存媒体流的引用
            mediaStream = stream

            // 初始化音频上下文
            audioContext = new AudioContext({
                sampleRate: sampleRate,
                latencyHint: 'interactive'
            })

            input = audioContext.createMediaStreamSource(stream)
            processor = audioContext.createScriptProcessor(bufferSize, 1, 1)

            input.connect(processor)
            processor.connect(audioContext.destination)

            // 设置音频处理
            setupAudioProcessing()

            // 初始化 WebSocket
            initWebSocket()
        } catch (error) {
            console.error('初始化音频失败:', error)
            showToast('初始化音频失败，正在重试...')
            // 如果失败，3秒后重试
            setTimeout(() => {
                triggerBtn.value?.click()
            }, 3000)
        }
    }

    // 设置音频处理
    const setupAudioProcessing = () => {
        processor.onaudioprocess = (e) => {
            if (!isAudioPlaying.value) {  // 只在非播放状态收集数据
                const inputData = e.inputBuffer.getChannelData(0)
                const pcmData = new Int16Array(inputData.length)
                for (let i = 0; i < inputData.length; i++) {
                    pcmData[i] = Math.max(-32768, Math.min(32767, inputData[i] * 0x7FFF))
                }
                accumulatedData.push(...pcmData)

                // 限制缓冲区大小，防止内存溢出
                if (accumulatedData.length > sampleRate * 3) {
                    accumulatedData = accumulatedData.slice(-sampleRate * 2)
                }
            }
        }
    }

    // 初始化 WebSocket
    const initWebSocket = () => {
        const token = localStorage.getItem('token')
        console.log('WebSocket URL:', interviewUrl + token)
        ws = new WebSocket(interviewUrl + token)

        ws.onopen = function () {
            console.log('WebSocket连接成功')
            ws.send(JSON.stringify({ "operation_type": "start", "interview_id": interviewRecordId.value }))

            // 启动固定间隔的音频发送
            if (audioSendTimer) {
                clearInterval(audioSendTimer)
            }
            audioSendTimer = setInterval(sendAudioData, 1000)
        }

        ws.onmessage = function (e) {
            console.log('收到消息：', e.data)
            try {
                const data = JSON.parse(e.data)
                if (data.code === 0 && data.data && data.data.question_url) {
                    // 在播放新音频前确保之前的音频已经停止
                    if (ttsPlayer.value) {
                        ttsPlayer.value.pause()
                        ttsPlayer.value.currentTime = 0
                    }
                    ttsPlayer.value.src = data.data.question_url
                    ttsPlayer.value.play()
                }
                if (data.data?.available_seconds !== undefined) {
                    if (initialDuration.value === 0) {
                        initialDuration.value = data.data.available_seconds
                    }
                    duration.value = data.data.available_seconds
                    if (duration.value <= 300) {
                        showTip.value = true
                    }
                }
                if (data.code === 500) {
                    handleEndInterview()
                }
            } catch (error) {
                console.error('处理消息失败:', error)
            }
        }

        ws.onclose = function (event) {
            console.log('WebSocket连接关闭:', event.code, event.reason)
        }

        ws.onerror = function (error) {
            console.error('WebSocket连接错误:', error)
        }
    }

    // 修改cleanup函数
    const cleanup = () => {
        // 清理音频发送定时器
        if (audioSendTimer) {
            clearInterval(audioSendTimer)
            audioSendTimer = null
        }

        if (ws) {
            try {
                ws.send(JSON.stringify({
                    operation_type: 'stop',
                    interview_id: interviewRecordId.value
                }))
                ws.close()
            } catch (error) {
                console.error('关闭WebSocket连接失败:', error)
            }
            ws = null
        }

        // 停止所有音轨
        if (mediaStream) {
            mediaStream.getTracks().forEach(track => {
                track.stop()
            })
            mediaStream = null
        }

        if (processor) {
            processor.disconnect()
            processor = null
        }

        if (input) {
            input.disconnect()
            input = null
        }

        if (audioContext) {
            audioContext.close()
            audioContext = null
        }

        accumulatedData = []
        isAudioPlaying.value = false
    }

    // 处理打断
    const handleInterrupt = () => {
        if (aiSpeaking.value) {
            ttsPlayer.value.pause()
        } else {
            ttsPlayer.value.play()
        }
    }

    // 切换静音
    const toggleMute = () => {
        isMuted.value = !isMuted.value
        ttsPlayer.value.muted = isMuted.value
    }

    // 格式化时间
    const formatTime = (seconds) => {
        // 确保秒数不为负
        const totalSeconds = Math.max(0, seconds)
        const minutes = Math.floor(totalSeconds / 60)
        const remainingSeconds = totalSeconds % 60
        return `${String(minutes).padStart(2, '0')}:${String(remainingSeconds).padStart(2, '0')}`
    }

    // 获取结束对话框的消息
    const getEndDialogMessage = () => {
        console.log(hasInterviewed.value)
        if (!hasInterviewed.value && duration.value < 300) { // 5分钟
            return '面试体验机会仅有一次，结束后将无法再次免费体验，可以选择继续面试，或者结束面试'
        }
        return '确定要结束本次面试吗？'
    }

    // 显示结束确认
    const showEndConfirm = () => {
        console.log('显示结束确认', duration.value, actualDuration.value)
        if (duration.value < MIN_DURATION || actualDuration.value < MIN_DURATION) { // 检查可用时长和实际面试时长
            showToast('面试时长不足5分钟，无法生成面试得分和建议')
        }
        showEndDialog.value = true
    }

    // 处理挂断
    const handleHangUp = async () => {
        // 检查可用时长和实际面试时长是否都满足5分钟
        // duration.value >= MIN_DURATION &&
        console.log(actualDuration.value, '实际面试时长')
        handleEndInterview()
    }
    // 处理结束面试
    const handleEndInterview = async () => {
        if (actualDuration.value >= MIN_DURATION) {
            // 调用生成打分接口
            await interviewApi.generateScoring({
                interview_id: interviewRecordId.value
            })
            ws.send(JSON.stringify({
                operation_type: 'stop',
                interview_id: interviewRecordId.value
            }))
            ws.close()
            router.replace({
                path: '/profile/interviews/detail',
                query: {
                    interview_record_id: interviewRecordId.value
                }
            })
        } else {
            showToast("面试时长不足五分钟，无法生成面试结果")
            router.replace('/home')
        }
    }

    onMounted(async () => {
        interviewRecordId.value = route.query.interview_record_id
        hasInterviewed.value = await interviewStore.checkInterviewHistory()

        // 监听音频播放状态
        ttsPlayer.value.addEventListener('play', () => {
            console.log('音频开始播放')
            aiSpeaking.value = true
            isAudioPlaying.value = true
            isUserSpeaking.value = false
        })
        // 监听音频结束
        ttsPlayer.value.addEventListener('ended', () => {
            console.log('音频结束播放')
            aiSpeaking.value = false
            isAudioPlaying.value = false
            isUserSpeaking.value = true
        })
        // 监听音频暂停
        ttsPlayer.value.addEventListener('pause', () => {
            console.log('音频暂停')
            aiSpeaking.value = false
            isAudioPlaying.value = false
            isUserSpeaking.value = true
        })

        // 自动触发开始按钮点击
        setTimeout(() => {
            console.log('自动触发开始按钮点击')
            triggerBtn.value?.click()
        }, 500)
    })

    onBeforeUnmount(() => {
        cleanup()
    })
</script>

<style lang="scss" scoped>
    .interview-voice {
        min-height: 100vh;
        background: linear-gradient(180deg, #000B24 0%, #000B24 100%);
        display: flex;
        flex-direction: column;
        align-items: center;
        padding: 20px;
        color: #fff;

        .top-tip {
            width: 100%;
            position: fixed;
            top: 10%;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(255, 77, 79, 0.1);
            color: #ff4d4f;
            border-radius: 20px;
            display: flex;
            align-items: center;
            font-size: 14px;

            .van-notice-bar {
                width: 100%;
            }

            .van-icon {
                margin-right: 4px;
            }
        }

        .interview-timer {
            font-size: 18px;
            margin: 10px 0 60px;
            opacity: 0.8;
        }

        .ai-avatar {
            margin-bottom: 20px;
            position: relative;
            display: flex;
            flex-direction: column;
            align-items: center;

            .avatar-bg {
                width: 120px;
                height: 120px;
                border-radius: 50%;
                background: rgba(255, 228, 186, 1);
                margin-bottom: 30px;
            }

            img {
                width: 100%;
                height: 100%;
                border-radius: 50%;
            }

            .voice-status {
                text-align: center;
                font-size: 16px;
                min-height: 24px;

                .wave-animation {
                    display: flex;
                    align-items: center;
                    gap: 4px;
                    height: 20px;

                    .wave-bar {
                        width: 8px;
                        height: 100%;
                        background-color: rgba(255, 255, 255, 1);
                        animation: waveAnim 1s ease-in-out infinite;
                        transform-origin: 50% 50%;

                        @for $i from 1 through 4 {
                            &:nth-child(#{$i}) {
                                animation-delay: $i * 0.1s;
                            }
                        }
                    }
                }
            }
        }

        .voice-tip {
            margin-top: 20px;
            display: flex;
            align-items: center;
            color: rgba(255, 255, 255, 0.6);
            font-size: 14px;

            .van-icon {
                margin-right: 4px;
            }
        }

        .control-bar {
            position: fixed;
            bottom: 40px;
            left: 0;
            right: 0;
            display: flex;
            justify-content: space-around;
            align-items: center;
            padding: 0 20px;

            .control-btn {
                display: flex;
                flex-direction: column;
                align-items: center;
                opacity: 0.8;
                transition: all 0.3s;

                &.active {
                    color: rgba(255, 255, 255, 1);
                }

                &.hang-up {
                    color: #ff4d4f;
                }

                img {
                    width: 80px;
                    height: 80px;
                    margin-bottom: 8px;
                }

                span {
                    font-size: 16px;
                }
            }

            .interrupt-btn {
                display: flex;
                flex-direction: column;
                align-items: center;
                background: rgba(255, 255, 255, 0.1);
                padding: 12px 24px;
                border-radius: 24px;
                transition: all 0.3s;

                &.disabled {
                    opacity: 0.5;
                    pointer-events: none;
                }

                .van-icon {
                    font-size: 28px;
                    margin-bottom: 8px;
                }

                span {
                    font-size: 14px;
                }
            }
        }
    }

    @keyframes waveAnim {

        0%,
        100% {
            transform: scaleY(0.5);
        }

        50% {
            transform: scaleY(1);
        }
    }

    // 弹窗样式覆盖
    :deep(.van-dialog) {
        .van-dialog__message {
            padding: 24px 16px;
            line-height: 1.6;
        }

        .van-button {
            height: 40px;
            font-size: 16px;
        }
    }
</style>